/**
 * 闭包就是可以访问自由函数的方法
 *
 * 闭包的应用:
 *  1. 函数柯里化
 *  2. 使用闭包实现方法/变量的私有化
 */

function getArea(width, height) {
    return width * height;
}



/**
 * 函数柯里化
 * @param {number} width 宽度
 * @returns 面积
 */
function getArea1(width) {
    // 这里返回一个函数,接受一个变量
    return height => {
        return width * height;
    }
}

/**
 * 定义一个返回固定宽度的函数
 */
const getTenWidth = getArea1(10);

const area1 = getTenWidth(10);
const area2 = getTenWidth(20);
const area3 = getTenWidth(30);
const area4 = getTenWidth(40);

console.log(area1, area2, area3, area4);

/**
 * 私有化方法/变量
 * 模块的概念,不会有命令的冲突
 * 每个模块的代码是相互独立的
 */
function funOne(i) {
    function funTwo() {
        console.log('数字' + i);
    }
    return funTwo;
}

const fa = funOne(110);
fa() // 返回的函数,直接调用,也是一个闭包的使用场景


/**
 * IIFE 匿名自执行函数
 */

const fooOne = (function () {
    var num = 0;
    return function () {
        num++;
        return num;
    }
})();

for (let i = 0; i < 10; i++) {
    console.log(fooOne(i));
}

/**
 * 缓存一些结果
 * 外部函数中创建了一个函数,闭包函数可以获取或者修改这个数据,并且延长了生命周期
 */

function funP() {
    let memo = [];
    function funTwo(i) {
        memo.push(i)
        console.log(memo.join(','));
    }
    return funTwo;
}

const fn = funP();
fn(1);
fn(2);
fn(3);

/**
 * 总结: 创建了私有变量
 *      延长了变量的生命周期
 */